/**
 * 
 */
package cn.dgfy.MyBatisStudy.service;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.dgfy.MyBatisStudy.bean.Student;
import cn.dgfy.MyBatisStudy.dao.StudentMapper;
import cn.dgfy.MyBatisStudy.test.StudentMapperTest;



/**
 * @author Tearfalls
 *
 */
@Service
public class StudentService {
	
	@Autowired
	private StudentMapper studentMapper;
	
	// 通过Spring自动装配机制拿到一个用于执行批量数据库操作的SqlSession，此SqlSession在Spring配置文件applicationContext.xml中以
	// bean的形式定义，在定义过程中指定了使用默认的SqlSessionFactory，并指定了ExecutorType为BATCH，因此这里拿到的SqlSession就是
	// 使用BatchExecutor的SqlSession
	@Autowired
	private SqlSession batchSqlSession;
	
	// 通过Spring自动装配机制拿到一个用于执行批量数据库操作的StudentMapper对象，此StudentMapper对象在Spring配置文件
	// applicationContext.xml中以bean的形式定义，在定义过程中指定了使用前面定义的使用BatchExecutor的batchSqlSession作为其执行的
	// SqlSession，即此StudentMapper就是以批量方式执行数据库操作的StudentMapper
	@Autowired
	private StudentMapper batchStudentMapper;
	
	public List<Student> get() {
		return studentMapper.get();
	}
	
	public Student getById(Integer id) {
		return studentMapper.getById(id);
	}
	
	/**
	 * 测试通过Spring自动装配机制提供批量执行SqlSession（BatchExecutor）进行批量数据库操作的功能
	 */
	// 虽然使用的是基于BatchExecutor的SqlSession，但是在Spring环境下，默认的SqlSession都是自动提交的，也就是说实际上虽然使用了基于
	// BatchExecutor的SqlSession，但实际的数据库操作还是以非批量的方式执行的，此时，如果想要以批量的方式执行数据库操作，就还需将包含
	// 有批量数据库操作的方法以@Transactional进行注解，以便使Spring对其开启事务，从而实现真正的批量操作
	@Transactional
	public void testAddBatch3() {
		// 为方便观察MyBatis日志信息，此处只生成20条学生信息用于插入测试，实际业务中通常会有更大数量级的批量操作需求
		List<Student> students = StudentMapperTest.generateRandomStudents(20);
		
		try {
			// 从基于BatchExecutor的SqlSessison得到Mapper代理对象，此代理对象就可用来执行批量数据库操作
			StudentMapper studentMapperBatch = batchSqlSession.getMapper(StudentMapper.class);
			
			// 将准备好的测试数写入事务，此过程中会在日志信息中显示出数据库操作执行的主要过程
			// 对于批量插入操作，此时输出的日志信息中将体现出只预编译（发送）了1次SQL语句，但是执行了20次设置参数的动作
			for (Student student : students) {
				studentMapperBatch.add(student);
			}
			
			// 由于由Spring来进行事务管理，且Spring在事务执行正常的情况下会自动提交事务，此处无法手动回滚事务
		} catch(Exception e) {
			e.getMessage();
		}
	}
	
	/**
	 * 测试通过Spring自动装配机制提供批量执行Mapper代理对象（使用BatchExecutor）进行批量数据库操作的功能
	 */
	// 虽然使用的是基于BatchExecutor的SqlSession，但是在Spring环境下，默认的SqlSession都是自动提交的，也就是说实际上虽然使用了基于
	// BatchExecutor的SqlSession，但实际的数据库操作还是以非批量的方式执行的，此时，如果想要以批量的方式执行数据库操作，就还需将包含
	// 有批量数据库操作的方法以@Transactional进行注解，以便使Spring对其开启事务，从而实现真正的批量操作
	@Transactional
	public void testAddBatch4() {
		// 为方便观察MyBatis日志信息，此处只生成20条学生信息用于插入测试，实际业务中通常会有更大数量级的批量操作需求
		List<Student> students = StudentMapperTest.generateRandomStudents(20);
		
		try {
			// 将准备好的测试数写入事务，此过程中会在日志信息中显示出数据库操作执行的主要过程
			// 对于批量插入操作，此时输出的日志信息中将体现出只预编译（发送）了1次SQL语句，但是执行了20次设置参数的动作
			for (Student student : students) {
				batchStudentMapper.add(student);
			}
			
			// 由于由Spring来进行事务管理，且Spring在事务执行正常的情况下会自动提交事务，此处无法手动回滚事务
		} catch(Exception e) {
			e.getMessage();
		}
	}
}
